package emulator.hardware.nmos6502.commands;

import emulator.EmulatorException;
import emulator.hardware.HwByte;
import emulator.hardware.nmos6502.Command;
import emulator.hardware.nmos6502.CommandSet;
import emulator.hardware.nmos6502.Cpu6502;
import emulator.hardware.nmos6502.Flags6502;
import emulator.hardware.nmos6502.Operand;
import emulator.hardware.nmos6502.operands.*;

/** ROL (ROtate Left)
 *  
 *  Affects Flags: S Z C
 *  
 *  MODE           SYNTAX       HEX LEN TIM
 *  Accumulator   ROL A         $2A  1   2
 *  Zero Page     ROL $44       $26  2   5
 *  Zero Page,X   ROL $44,X     $36  2   6
 *  Absolute      ROL $4400     $2E  3   6
 *  Absolute,X    ROL $4400,X   $3E  3   7
 *  
 *  ROL shifts all bits left one position. The Carry is shifted into bit 0 and
 *  the original bit 7 is shifted into the Carry. 
 */
public class ROL implements Command {

	@Override
	public void execute(Cpu6502 cpu, Operand operand) throws EmulatorException {
		Flags6502 flags = cpu.getFlags();
		HwByte value = operand.getByte();
		boolean new_carry = value.getBit(7);
		value.shift(1);
		value.setBit(0, flags.getCarry());
		operand.setByte(value);
		flags.setNZFromValue(value);
		flags.setCarry(new_carry);
		cpu.setFlags(flags);
	}

	@Override
	public String getName() {
		return "ROL";
	}

	@Override
	public void register(CommandSet cset) {
		cset.defineCommand(0x2A, this, new Accumulator());
		cset.defineCommand(0x26, this, new ZeroPage(), 4);
		cset.defineCommand(0x36, this, new ZeroPageX(), 4);
		cset.defineCommand(0x2E, this, new Absolute(), 4);
		cset.defineCommand(0x3E, this, new AbsoluteX(false), 5);
	}

}
